package com.course.web.component.base;

import com.course.util.TimeUtils;
import com.google.common.collect.Lists;
import com.vaadin.data.HasValue;
import com.vaadin.event.EventRouter;
import com.vaadin.shared.Registration;
import com.vaadin.ui.ComboBox;
import com.vaadin.ui.CustomComponent;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.Label;

import java.util.List;

public class TimeBox extends CustomComponent implements HasValue<Integer> {

    static {
        List<Integer> houList = Lists.newArrayListWithCapacity(24);
        List<Integer> minList = Lists.newArrayListWithCapacity(60);
        for (int i = 0; i < 24; i++) {
            houList.add(i);
        }
        for (int i = 0; i < 60; i++) {
            minList.add(i);
        }
        HOU_LIST = houList;
        MIN_LIST = minList;
    }


    private static final List<Integer> HOU_LIST;
    private static final List<Integer> MIN_LIST;

    private final ComboBox<Integer> houBox;
    private final ComboBox<Integer> minBox;

    private int time;
    private int hou;
    private int min;
    private boolean readOnly;
    private EventRouter eventRouter;

    public TimeBox(String caption) {
        this.time = TimeUtils.toTime(hou, min);
        this.houBox = new ComboBox<>(null, HOU_LIST);
        this.minBox = new ComboBox<>(null, MIN_LIST);

        HorizontalLayout layout = new HorizontalLayout();
        layout.addComponent(houBox);
        layout.addComponent(new Label(":"));
        layout.addComponent(minBox);
        setCompositionRoot(layout);
        setCaption(caption);

        houBox.setValue(hou);
        minBox.setValue(min);
        houBox.addValueChangeListener(this::onHouChange);
        minBox.addValueChangeListener(this::onMinChange);
    }

    private void onHouChange(ValueChangeEvent<Integer> event) {
        int oldValue = time;
        hou = event.getValue();
        time = TimeUtils.toTime(hou, min);
        onChange(oldValue);
    }

    private void onMinChange(ValueChangeEvent<Integer> event) {
        int oldValue = time;
        min = event.getValue();
        time = TimeUtils.toTime(hou, min);
        onChange(oldValue);
    }

    private void onChange(int oldValue) {
        ValueChangeEvent<Integer> event = new ValueChangeEvent<>(this, this, oldValue, true);
        for (Object o : eventRouter.getListeners(ValueChangeEvent.class)) {
            ValueChangeListener<Integer> listener = (ValueChangeListener<Integer>) o;
            listener.valueChange(event);
        }
    }

    @Override
    public void setValue(Integer value) {
        time = value;
        hou = TimeUtils.getHH(time);
        min = TimeUtils.getMM(time);
        houBox.setValue(hou);
        minBox.setValue(min);
    }

    @Override
    public Integer getValue() {
        return time;
    }

    @Override
    public void setRequiredIndicatorVisible(boolean requiredIndicatorVisible) {

    }

    @Override
    public boolean isRequiredIndicatorVisible() {
        return true;
    }

    @Override
    public void setReadOnly(boolean readOnly) {
        this.readOnly = readOnly;
    }

    @Override
    public boolean isReadOnly() {
        return readOnly;
    }

    @Override
    public Registration addValueChangeListener(ValueChangeListener<Integer> listener) {
        if (eventRouter == null) {
            eventRouter = new EventRouter();
        }
        return eventRouter.addListener(ValueChangeEvent.class, listener, "valueChange");
    }


}
